package gin_plugin

import (
	"fmt"
	"gitee.com/kristas/booting-go/framework/common/util/lang"
	"gitee.com/kristas/booting-go/framework/core/log"
	"gitee.com/kristas/booting-go/framework/core/statement/types"
	"gitee.com/kristas/booting-go/framework/web"
	"github.com/gin-gonic/gin"
	"net/http"
	"regexp"
)

type Starter struct {
	types.Component
	app *gin.Engine
	Log log.Logger `wire:""`
}

func NewStarter() *Starter {
	return &Starter{}
}

func (s *Starter) Init() error {
	gin.SetMode(gin.ReleaseMode)
	engine := gin.New()
	engine.Use(gin.Recovery())
	s.app = engine
	return nil
}

func (s *Starter) RegisterEndpoint(endpoint web.Endpoint) {
	info := endpoint.GetApiInfo()
	s.app.Handle(info.GetHttpMethod(), pathVariableParser(info.GetURL()), func(ctx *gin.Context) {
		endpoint.Handler(newParamAdapter(ctx), func(result interface{}) error {
			ctx.JSON(http.StatusOK, result)
			return nil
		})
	})
}

func (s *Starter) FsHandler(prefix, dir string) {
	s.app.Static(prefix, dir)
}

func (s *Starter) ListenAndServe(port int) error {
	return s.app.Run(fmt.Sprintf(":%d", port))
}

func pathVariableParser(url string) string {
	compile := regexp.MustCompile("{\\w+}")
	vars := compile.FindAllString(url, -1)
	t := lang.NewString(url)
	for _, v := range vars {
		pv := lang.NewString(v).RemovePrefix("{").RemoveSuffix("}").String()
		t = t.Replace(v, ":"+pv, 1)
	}
	return t.String()
}
